package com.easymin.daijia.server.compute;

import com.alibaba.fastjson.JSONArray;
import com.easymin.daijia.server.TestBase;
import com.easymin.daijia.server.service.ZhuanServiceTest;
import com.ybkj.daijia.DateTimeUtils;
import com.ybkj.daijia.serverUtils.GPSTransformUtils;
import com.ybkj.daijia.api.baidu.BaiduApi;
import com.ybkj.daijia.api.baidu.BaiduApiTestImpl;
import com.ybkj.daijia.cache.SmallLocationImpl;
import com.ybkj.daijia.cache.SmallLocationServiceTest;
import com.ybkj.daijia.server.mapper.OrderLocationManyMapper;
import com.ybkj.daijia.server.model.OrderLocation;
import com.ybkj.daijia.server.model.OrderLocationMany;
import com.ybkj.daijia.server.service.ZhuancheService;
import com.ybkj.daijia.server.zhuan.Order;
import com.ybkj.daijia.server.zhuan.SmallLocation;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author zhyu
 * @date
 */
public class ComputeMilesByManyLocations extends TestBase {

    public static final String md_template1 = "# <center> ${datetime}上车测试里程分析</center>\n" +
        "\n" +
        "### 分析\n" +
        "> \n" +
        "\n" +
        "\n" +
        "### 每单轨迹路程计算\n" +
        "\n" +
        "|         单号          |时间|  价格(起步价,里程价,时间价,远程费,等待费) |       开始地         |       目的地       | 当时里程计算(km) | 当时里程来源 | local计算 (km)  | 百度计算(km) | 高德计算(km) | 订单耗时(分) | 点数目 | 点平均间隔(ms) | 点最大间隔(ms) |                      最大间隔时间和原因                       |              点评估              |两点百度轨迹计算|两点local|两点高德|滴滴预估路程(km)|滴滴预估时间|滴滴预估价格|最后即时预估价格|\n"
        +
        "| -------------------- |--|--|--| ---|---|---------------------- | ------------------ | --------------- | ----------- | ------------- | ----------- | ------- | ------- | ----------- | ----- | -------- | --------- | ----------------------------------------------------------- | ------------------------------- |--|--|--|\n";
    public static final String md_tempalte2 = "| ${orderNo}/${orderId} | ${orderStartTime}-${orderEndTime}|${totalPrice}(${qibuPrice},${distancePrice}, ${timePrice},${remotePrice},${waitPrice})|${startPlace}     | ${distination}          | ${distance}             |           |   ${local}      | ${baidu}    | ${gaode}    | ${costTime}          | ${size}    | ${avg}      | ${max}     | ${start} - ${end}                     |              |${twoBaidu}|${twoLocal}|${twoGaode}|||||\n";
    private SmallLocationImpl smallLocation;
    private OrderLocationManyMapper manyMapper = session.getMapper(OrderLocationManyMapper.class);
    private ZhuancheService zhuancheService = new ZhuanServiceTest();
    private Logger logger = LoggerFactory.getLogger(ComputeMilesByManyLocations.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");

    public ComputeMilesByManyLocations() throws IOException {
        smallLocation = new SmallLocationImpl();
        BaiduApi baiduApi = new BaiduApiTestImpl();
        smallLocation.setBaiduApi(baiduApi);
    }

    @Test
    public void test1() {
        List<OrderLocationMany> orderLocationManies_dr = manyMapper
            .selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche, 372L);
        List<SmallLocation> dr = JSONArray
            .parseArray(orderLocationManies_dr.get(0).getJsonLocs(), SmallLocation.class);
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < dr.size(); i++) {
            if (i == dr.size() - 1) {
                sb.append(dr.get(i).printBD()).append("]");
            } else {
                sb.append(dr.get(i).printBD()).append(",");
            }
        }
        System.out.println(sb.toString());
    }

    /***
     * 生成md
     */
    @Test
    public void gen() {
        String date = DateTimeUtils.DATE_FORMAT_DATE.format(new Date());
        StringBuilder sb = new StringBuilder();
        sb.append(md_template1.replace("${datetime}", date));
        long end = 405L;
        long start = 393L;
//        long[] ids = {388L,389L,390L};
        for (long i = start; i <= end; i++) {
            print(sb, i);
        }
        System.out.println("\n");
        System.out.println(sb.toString());
    }

    public void testSmallPoint() {

    }

    @Test
    public void testBaiduCount() throws InterruptedException {
        long id = 370L;
        Order one = zhuancheService.findOne(id);
        logger.debug("最终距离,直线距离,耗时,百度api耗时,时间差,本点,上一点");
        logger.debug(sdf.format(new Date()) + "开始测试订单号" + id + ",,,,,,");
        List<OrderLocationMany> orderLocationManies_dr = manyMapper
            .selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche, id);
        List<SmallLocation> dr = JSONArray
            .parseArray(orderLocationManies_dr.get(0).getJsonLocs(), SmallLocation.class);
        SmallLocationImpl smallLocationService = new SmallLocationServiceTest();
        smallLocationService.setBaiduApi(new BaiduApiTestImpl());
        for (int i = 0; i < 100000; i++) {
            Double baidu = smallLocationService.computeTotalMilesBaidu(new ArrayList<>(dr));
            Thread.sleep(1500);
            if (baidu != null) {
//                log.info(baidu.toString());
            }
        }
    }

    @Test // 2(5953,6262) a(6957,6044)
    public void compute() {
        long id = 370L;
        Order one = zhuancheService.findOne(id);
        logger.debug("最终距离,直线距离,耗时,百度api耗时,时间差,本点,上一点");
        logger.debug(sdf.format(new Date()) + "开始测试订单号" + id + ",,,,,,");
        List<OrderLocationMany> orderLocationManies_dr = manyMapper.selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche, id);
//        List<OrderLocationMany> orderLocationManies_pa = manyMapper.selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche_pa, id);
        List<SmallLocation> dr = JSONArray.parseArray(orderLocationManies_dr.get(0).getJsonLocs(), SmallLocation.class);
//        List<SmallLocation> pa = JSONArray.parseArray(orderLocationManies_pa.get(0).getJsonLocs(), SmallLocation.class);
        long start1 = System.currentTimeMillis();

//        List<SmallLocation> dr = new ArrayList<>();
////        dr.add(sm.get(0));
////        dr.add(sm.get(sm.size() - 1));

        System.out.println("开始统计");
        long max = -1L;
        long min = 0L;
        long sum = -1L;
        long start = -1L;
        long end = -1L;
        double size = dr.size();
        for (int i = 0; i < dr.size() - 1; i++) {
            SmallLocation th = dr.get(i);
            SmallLocation next = dr.get(i + 1);
            long sub = next.getLocDate() - th.getLocDate();
            sum += sub;
            if (min > sub) {
                min = sub;
            }
            if (max < sub) {
                max = sub;
                start = th.getLocDate();
                end = next.getLocDate();
            }
        }
        double avg = sum / size;
        String startAddress = one.getStartAddress();
        String endAddress = one.getEndAddress();
        SmallLocationImpl smallLocationService = new SmallLocationServiceTest();
        smallLocationService.setBaiduApi(new BaiduApiTestImpl());
        Double local = smallLocationService.computeTotalMilesLocal(new ArrayList<>(dr));
        Double baidu = smallLocationService.computeTotalMilesBaidu(new ArrayList<>(dr));
        for (SmallLocation location : dr) {
            GPSTransformUtils.bd09_To_Gcj02(location);
        }
        Double gaoDe = smallLocationService.computeTotalMilesGaoDe(new ArrayList<>(dr));
//        long start2 = System.currentTimeMillis();
//        StringBuilder sb = new StringBuilder();

//        System.out.println(sb);
//        Double miles = this.smallLocation.filterAndComputeMiles(co);
//        long end = System.currentTimeMillis();
//        System.out.println(miles);
        logger.info("统计点有{}个, 最大间隔{}和发生时间{} - {}, 最小间隔{}, 平均间隔{}, local {}, 百度 {},高德 {}", size, max,
            new Date(start), new Date(end), min, avg, local, baidu, gaoDe);
    }

    public void print(StringBuilder sb, Long orderId) {
        long id = orderId;
        Order one = zhuancheService.findOne(id);
        logger.debug("最终距离,直线距离,耗时,百度api耗时,时间差,本点,上一点");
        logger.debug(sdf.format(new Date()) + "开始测试订单号" + id + ",,,,,,");
        List<OrderLocationMany> orderLocationManies_dr = manyMapper
            .selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche, id);
//        List<OrderLocationMany> orderLocationManies_pa = manyMapper.selectByOrderTypeAndOrderId(OrderLocation.OrderType.zhuanche_pa, id);
        List<SmallLocation> dr = JSONArray
            .parseArray(orderLocationManies_dr.get(0).getJsonLocs(), SmallLocation.class);
//        List<SmallLocation> pa = JSONArray.parseArray(orderLocationManies_pa.get(0).getJsonLocs(), SmallLocation.class);
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        String orderStartTime = sdf.format(one.getCreated());
        String orderEndTime = sdf.format(one.getUpdated());
        Double realPay = one.getRealPay();
        DecimalFormat df = new DecimalFormat("#.00");
        String totalPrice = String.valueOf(realPay);
        String distancePrice = String.valueOf(one.getMileagePrice());
        String timePrice = String.valueOf(one.getRunTimePrice());
        String remotePrice = String.valueOf(one.getYuanchengMoney());
        String waitPrice = String.valueOf(one.getWaitPrice());
        String qibuPrice = String.valueOf(one.getStartPrice());

        System.out.println("开始统计");
        long max = -1L;
        long min = 0L;
        double sum = 0L;
        long start = -1L;
        long end = -1L;
        int size = dr.size();
        for (int i = 0; i < dr.size() - 1; i++) {
            SmallLocation th = dr.get(i);
            SmallLocation next = dr.get(i + 1);
            long sub = next.getLocDate() - th.getLocDate();
            sum += sub;
            if (min > sub) {
                min = sub;
            }
            if (max < sub) {
                max = sub;
                start = th.getLocDate();
                end = next.getLocDate();
            }
        }
        double avg = sum / size;
        String startAddress = one.getStartAddress();
        String endAddress = one.getEndAddress();
        SmallLocationImpl smallLocationService = new SmallLocationServiceTest();
        smallLocationService.setBaiduApi(new BaiduApiTestImpl());
        Double local = smallLocationService.computeTotalMilesLocal(new ArrayList<>(dr));
        if (local != null) {
            local /= 1000;
        } else {
            local = 0d;
        }

        Double baidu = smallLocationService.computeTotalMilesBaidu(new ArrayList<>(dr));
        if (baidu != null) {
            baidu /= 1000;
        } else {
            baidu = 0d;
        }

        for (SmallLocation location : dr) {
            GPSTransformUtils.bd09_To_Gcj02(location);
        }
        Double gaoDe = smallLocationService.computeTotalMilesGaoDe(new ArrayList<>(dr));
        if (gaoDe != null) {
            gaoDe /= 1000;
        } else {
            gaoDe = 0d;
        }
        List<SmallLocation> two = new ArrayList();
        two.add(dr.get(0));
        two.add(dr.get(dr.size() - 1));
        Double twoBaidu = smallLocationService.computeTotalMilesBaidu(new ArrayList<>(two));
        if (twoBaidu != null) {
            twoBaidu /= 1000;
        } else {
            twoBaidu = 0d;
        }
        Double twoLocal = smallLocationService.computeTotalMilesLocal(new ArrayList<>(two));
        if (twoLocal != null) {
            twoLocal /= 1000;
        } else {
            twoLocal = 0d;
        }
        for (SmallLocation location : two) {
            GPSTransformUtils.bd09_To_Gcj02(location);
        }
        Double twoGaode = smallLocationService.computeTotalMilesGaoDe(new ArrayList<>(two));
        if (twoGaode != null) {
            twoGaode /= 1000;
        } else {
            twoGaode = 0d;
        }

        String word = md_tempalte2.replace("${orderNo}", one.getOrderNo())
            .replace("${orderId}", String.valueOf(orderId)).replace("${startPlace}", startAddress)
            .replace("${distination}", endAddress)
            .replace("${distance}", String.valueOf(one.getMileage()))
            .replace("${local}", df.format(local))
            .replace("${baidu}", df.format(baidu)).replace("${gaode}", df.format(gaoDe))
            .replace("${costTime}", String.valueOf(one.getRunTime() / 60))
            .replace("${size}", String.valueOf(size)).replace("${max}", String.valueOf(max))
            .replace("${start}", new Date(start).toString())
            .replace("${avg}", df.format(avg)).replace("${end}", new Date(end).toString())
            .replace("${twoBaidu}", String.valueOf(twoBaidu))
            .replace("${twoLocal}", String.valueOf(twoLocal))
            .replace("${twoGaode}", String.valueOf(twoGaode))
            .replace("${orderStartTime}", orderStartTime).replace("${orderEndTime}", orderEndTime)
            .replace("${totalPrice}", totalPrice).replace("${qibuPrice}", qibuPrice)
            .replace("${distancePrice}", distancePrice).replace("${timePrice}", timePrice)
            .replace("${remotePrice}", remotePrice).replace("${waitPrice}", waitPrice);
        logger.info("统计点有{}个, 最大间隔{}和发生时间{} - {}, 最小间隔{}, 平均间隔{}, local {}, 百度 {},高德 {}", size, max,
            new Date(start), new Date(end), min, avg, local, baidu, gaoDe);
        sb.append(word);
    }
}
